package com.google.code.yargon.level;

import org.apache.log4j.Logger;
import com.google.code.yargon.util.LogUtil;

@SuppressWarnings("serial")
public class Route extends LocationSet {

	private Logger log = LogUtil.getInstance();
	
	private Location src;
	private Location dest;
	//private LinkedList<Location> wayPoints = null;
	
	// Max and min coordinates encountered
	private int minX = 0;
	private int maxX = 0;
	private int minY = 0;
	private int maxY = 0;
	
	// Is the route solved or not
	boolean solved = false;
	
	/**
	 * Construct a new route with end points
	 */
	public Route(Location src, Location dest) {
		super();
		this.src = src;
		this.dest = dest;
	}
	
	/**
	 * Set the source location
	 * 
	 * @param src
	 */
	public void setSource(Location src) {
		this.src = src;
	}
	
	/**
	 * Set the destination
	 * 	
	 * @param dest
	 */
	public void setDestination(Location dest) {
		this.dest = dest;
	}
	
	/**
	 * Get the source location
	 * 
	 * @return
	 */
	public Location getSource() {
		return this.src;
	}
	
	/**
	 * Get the destination
	 * 
	 * @return
	 */
	public Location getDestination() {
		return this.dest;
	}
	
	/**
	 * Mark the route as solved
	 * 
	 */
	public void solve() {
		this.solved = true;
	}
	
	/**
	 * Return true if the route is solved
	 * 
	 * @return
	 */
	public boolean isSolved() {
		return this.solved;
	}
			
	/**
	 * Push new way point to the route by Location
	 * 
	 * @param l
	 */
	@Override
	public void push(Location l) {
		if(size() == 0 || ! l.equals(getLast())) {		// Add if it is first way point or differs from the previously inserted
			add(l);
			log.trace("New waypoint ("+size()+"): "+l.getX()+","+l.getY());
		} else {
			log.trace("New waypoint equals previous, discarding");
		}
		
		// Keep track of boundaries
		if(l.getX() < minX) {
			minX = l.getX();
		}
		if(l.getX() > maxX) {
			maxX = l.getX();
		}
		if(l.getY() < minY) {
			minY = l.getY();
		}
		if(l.getY() > maxY) {
			maxY = l.getY();
		}
	}
	
	/**
	 * Return route as normalized area (lower left corner being at 0,0)
	 */
	public Area getRouteArea() {
		Area a = new Area(maxX - minX + 1, maxY - minY + 1);
		for(Location l : this) {
			int nX = l.getX() - minX;
			int nY = l.getY() - minY;
			a.put(nX, nY, new FloorBlock());
		}
		return a;
	}
	
	/** 
	 * Return a string containing all way point coordinates
	 */
	public String toString() {
		String pathStr = "";
		for(Location l : this) {
			pathStr += l.toString()+", ";
		}
		return pathStr;
	}
}
